package com.icss.train_sys_back.controller.home;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.icss.train_sys_back.config.AlipayConfig;
import com.icss.train_sys_back.entity.home.OrderEntity;
import com.icss.train_sys_back.mapper.home.OrderMapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * 支付宝支付控制器
 * 处理支付宝支付相关的HTTP请求
 */
@RestController
@RequestMapping("/api/alipay")
@Validated
public class AlipayController {
    private static final Logger logger = LoggerFactory.getLogger(AlipayController.class);
    private static final ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private AlipayConfig alipayConfig;

    @Autowired
    private OrderMapper orderMapper;

    /**
     * 创建支付宝支付表单
     */
    @PostMapping("/createForm")
    public String createForm(@RequestParam("orderId") String orderId,
                             @RequestParam("total_price") String totalPrice,
                             @RequestParam("subject") String subject,
                             @RequestParam("return_url") String returnUrl,
                             @RequestParam(value = "notify_url", required = false) String notifyUrl) { // 添加可选的notify_url参数
        logger.info("收到支付宝支付请求，订单号：{}", orderId);


        try {
            // 1. 构造客户端
            AlipayClient alipayClient = new DefaultAlipayClient(
                    alipayConfig.getGatewayUrl(),
                    alipayConfig.getAppId(),
                    alipayConfig.getMerchantPrivateKey(),
                    "json",
                    alipayConfig.getCharset(),
                    alipayConfig.getAlipayPublicKey(),
                    alipayConfig.getSignType()
            );

            // 2. 创建API对应的request
            AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
            request.setReturnUrl(returnUrl);
            // 优先使用前端传递的notify_url，如果没有则使用配置文件中的
            request.setNotifyUrl(StringUtils.hasText(notifyUrl) ? notifyUrl : alipayConfig.getNotifyUrl());

            // 3. 设置业务参数
            Map<String, Object> bizContent = new HashMap<>();
            bizContent.put("out_trade_no", orderId);
            bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
            bizContent.put("total_amount", totalPrice);
            bizContent.put("subject", subject);
            bizContent.put("body", "中国梦想游票务订单");

            // 使用Jackson将Map转换为标准JSON字符串
            String jsonBizContent = objectMapper.writeValueAsString(bizContent);
            request.setBizContent(jsonBizContent);

            logger.info("构建支付宝请求参数：{}", jsonBizContent);

            // 4. 调用SDK生成表单
            AlipayTradePagePayResponse response = alipayClient.pageExecute(request);
            if (response.isSuccess()) {
                logger.info("支付宝表单生成成功，订单号：{}", orderId);
                return response.getBody();
            } else {
                logger.error("生成支付表单失败，订单号：{}，错误信息：{}", orderId, response.getMsg());
                throw new RuntimeException("生成支付表单失败: " + response.getMsg());
            }
        } catch (AlipayApiException e) {
            logger.error("支付宝接口调用失败，订单号：{}", orderId, e);
            throw new RuntimeException("支付宝接口调用失败", e);
        } catch (Exception e) {
            logger.error("处理支付请求异常，订单号：{}", orderId, e);
            throw new RuntimeException("处理支付请求异常", e);
        }
    }

    /**
     * 检查支付状态 - 精简参数，只保留必要的orderId
     */
    @GetMapping("/checkStatus")
    public Map<String, Object> checkStatus(@RequestParam("orderId") String orderId) {
        logger.info("检查订单支付状态，订单号：{}", orderId);
        Map<String, Object> result = new HashMap<>();

        try {
            // 验证订单号
            if (!StringUtils.hasText(orderId)) {
                throw new IllegalArgumentException("订单号不能为空");
            }

            OrderEntity order = (OrderEntity) orderMapper.selectByOrderId(orderId);
            if (order != null) {
                if (order.getOrderStatus() == 1) {
                    logger.info("订单支付成功，订单号：{}", orderId);

                    result.put("status", "SUCCESS");
                    result.put("message", "支付成功");
                } else {
                    logger.info("订单等待支付，订单号：{}，当前状态：{}", orderId, order.getOrderStatus());
                    result.put("status", "WAITING");
                    result.put("message", "等待支付");
                }
            } else {
                logger.warn("未找到订单信息，订单号：{}", orderId);
                result.put("status", "NOT_FOUND");
                result.put("message", "未找到订单信息");
            }
        } catch (IllegalArgumentException e) {
            logger.warn("参数校验失败：{}", e.getMessage());
            result.put("status", "ERROR");
            result.put("message", e.getMessage());
        } catch (Exception e) {
            logger.error("查询支付状态异常，订单号：{}", orderId, e);
            result.put("status", "ERROR");
            result.put("message", "查询失败");
        }
        return result;
    }

    /**
     * 异步通知处理
     * 支付宝服务器会在用户支付成功后调用此接口
     */
    @PostMapping("/notify/{orderId}")
    public String notify(@PathVariable("orderId") String orderId) {
        logger.info("收到支付宝异步通知 orderId = {}",orderId);
        // 更新订单状态为已支付
        int count = orderMapper.updateOrderStatus2(orderId);
        if (count > 0) {
            logger.info("订单{}支付成功，状态已更新", orderId); // 修复日志格式
            return "success"; // 必须返回success，否则支付宝会继续通知
        } else {
            logger.warn("订单{}更新状态失败，未找到对应订单", orderId); // 修复日志格式
            return "fail"; // 仍返回success避免重复通知
        }
    }
}
